package com.larrylague.template.data
{
	import flash.display.CapsStyle;
	import flash.display.JointStyle;
	import flash.display.LineScaleMode;
	import flash.display.Shape;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.text.AntiAliasType;
	import flash.text.Font;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
	import flash.text.TextFormatAlign;
	
	import org.casalib.collection.List;
	import org.osflash.thunderbolt.Logger;
	
	public class AbstractModel extends EventDispatcher
	{
		protected var _path:String;
		protected var _xml:XML;
		protected var _items:List;
		protected var _activeIndex:int = -1;
		
		
		///////////////////////////////////////////////////////////////////////////////////////////////////////
		// CONSTRUCTOR
		///////////////////////////////////////////////////////////////////////////////////////////////////////
		
		public function AbstractModel()
		{
			
		}
		
		
		///////////////////////////////////////////////////////////////////////////////////////////////////////
		// PUBLIC METHODS
		///////////////////////////////////////////////////////////////////////////////////////////////////////
		
		public static function getTextField(size:int, font:String, color:uint, multiline:Boolean = false, 
											width:int = 0, wordwrap:Boolean = false, leading:Number = 0, 
											align:String = TextFormatAlign.LEFT, embedFonts:Boolean = false):TextField
		{
			var fmt:TextFormat = new TextFormat();
			fmt.font = font;
			fmt.size = size;
			fmt.color = color;
			fmt.leading = leading;
			fmt.align = align;
			var tf:TextField = new TextField();
			tf.defaultTextFormat = fmt;
			tf.autoSize = TextFieldAutoSize.LEFT;
			tf.antiAliasType = AntiAliasType.ADVANCED;
			tf.embedFonts = embedFonts;
			tf.multiline = multiline;
			tf.wordWrap = wordwrap;
			if (width != 0) tf.width = width;
			
			return tf;
		}
		
		public static function drawSquare(width:int, height:int, fillColor:uint, fillAlpha:Number, lineColor:int = -1):Shape
		{
			var sp:Shape = new Shape();
			if (lineColor != -1) sp.graphics.lineStyle(1, lineColor, 1, true, LineScaleMode.NORMAL, CapsStyle.SQUARE, JointStyle.MITER);
			sp.graphics.beginFill(fillColor, fillAlpha);
			sp.graphics.drawRect(0, 0, width, height);
			sp.graphics.endFill();
			
			return sp;
		}
		
		public static function traceFonts():void
		{
			for each (var font:Font in Font.enumerateFonts()) {
				Logger.debug("Embedded font: " + font.fontName);
			}
		}
		
		public function loadXML(path:String):void
		{
			_path = path;
			
			var ldr:URLLoader = new URLLoader();
			ldr.addEventListener(IOErrorEvent.IO_ERROR, handleIOError);
			ldr.addEventListener(ProgressEvent.PROGRESS, handleProg);
			ldr.addEventListener(Event.COMPLETE, handleLoaded);
			ldr.load(new URLRequest(_path));
		}
		
		public function get items():List
		{
			return _items;
		}
		
		public function get activeIndex():int
		{
			return _activeIndex;
		}
		
		public function set activeIndex(value:int):void
		{
			if (_activeIndex == value || value < 0) return;
			_activeIndex = value;
			dispatchEvent(new Event(Event.CHANGE));
		}
		
		
		///////////////////////////////////////////////////////////////////////////////////////////////////////
		// EVENT HANDLERS
		///////////////////////////////////////////////////////////////////////////////////////////////////////
		
		protected function handleIOError(event:IOErrorEvent):void
		{
			Logger.error("IO Error: " + event.text);
		}
		
		protected function handleProg(event:ProgressEvent):void
		{
			dispatchEvent(new ProgressEvent(ProgressEvent.PROGRESS, false, false, event.bytesLoaded, event.bytesTotal));
		}
		
		protected function handleLoaded(event:Event):void
		{
			URLLoader(event.target).removeEventListener(IOErrorEvent.IO_ERROR, handleIOError);
			URLLoader(event.target).removeEventListener(ProgressEvent.PROGRESS, handleProg);
			URLLoader(event.target).removeEventListener(Event.COMPLETE, handleLoaded);
			
			_xml = new XML(event.target.data);
			_items = new List();
			
			buildChildren();
		}
		
		protected function buildChildren():void
		{
			dispatchEvent(new Event(Event.COMPLETE));
		}
	}
}